//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------
/*
*/

package uxgenes.ext.camera;

import java.util.List;

import uxgenes.core.EngineContext;
import uxgenes.core.Logger;
import uxgenes.core.UXUtils;
import android.os.Handler;
import android.view.SurfaceHolder;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;




//
// Camera
//

public final class UXCamera
				// #ifdef CAMERA
				implements
					uxgenes.ext.IExtension,
					SurfaceHolder.Callback,
					Camera.PictureCallback,
					Camera.AutoFocusCallback
				// #endif CAMERA
{

	// #ifdef CAMERA
	
// constants //
	private	static final String		TAG = "UXCamera";
	//private static final int		DEF_RESERVED_BUFFERS = 2;
	//private static final int		MAX_RESERVED_BUFFERS = 10;
	
// commands //
	public static final int			COM_OPEN 					= 0x0001;
	public static final int			COM_CLOSE 					= 0x0002;
	public static final int			COM_START_FACE_DETECTION	= 0x0003;
	public static final int			COM_STOP_FACE_DETECTION		= 0x0004;
	public static final int			COM_AUTO_FOCUS				= 0x0005;
	public static final int			COM_UPDATE_ZOOM_INFO		= 0x0006;
	// shared
	public static final int			COM_SET_ZOOM				= 0x1001;
	public static final int			COM_SET_ZOOM_NORM			= 0x1002;	// normalized value
	public static final int			COM_SET_SMOOTH_ZOOM			= 0x1003;
	public static final int			COM_SET_SMOOTH_ZOOM_NORM	= 0x1004;	
	public static final int			COM_SET_EXPOSURE			= 0x1005;
	public static final int			COM_SET_EFFECT				= 0x1006;
	public static final int			COM_SET_FLASH_MODE			= 0x1007;
	public static final int			COM_SET_FOCUS_MODE			= 0x1008;
	public static final int			COM_SET_SCENE_MODE			= 0x1009;
	public static final int			COM_SET_WHITE_BALANCE		= 0x1010;
	public static final int			COM_SET_ANTIBANDING			= 0x1011;	
	public static final int			COM_SET_EXPOSURE_NORM		= 0x1012;
	// preview
	public static final int			COM_SET_PREVIEW_SIZE		= 0x2001;
	public static final int			COM_SET_PREVIEW_FORMAT		= 0x2002;
	public static final int			COM_SET_PREVIEW_FPS			= 0x2003;
	public static final int			COM_SET_PREVIEW_NEAR_SIZE	= 0x2004;
	public static final int			COM_SET_PREVIEW_NEAR_FPS	= 0x2005;
	//public static final int			COM_SET_PREVIEW_BUFFERS		= 0x2006;
	public static final int			COM_SET_PREVIEW_TEXTURE		= 0x2007;
	//public static final int			COM_START_PREVIEW			= 0x2008;
	//public static final int			COM_STOP_PREVIEW			= 0x2009;
	// picture
	public static final int			COM_TAKE_PICTURE			= 0x3000;
	public static final int			COM_SET_PICTURE_SIZE		= 0x3001;
	public static final int			COM_SET_PICTURE_FORMAT		= 0x3002;
	public static final int			COM_SET_PICTURE_NEAR_SIZE	= 0x3003;
	public static final int			COM_SET_JPEG_QUALITY		= 0x3004;
	
// enums //
	// antibanding //
	public static final int			ANTIBANDING_OFF  	= 0;
	public static final int			ANTIBANDING_50HZ  	= 1;
	public static final int			ANTIBANDING_60HZ 	= 2;
	public static final int			ANTIBANDING_AUTO 	= 3;
	
	// color effect //
	public static final int			EFFECT_NONE 		= 0;
	public static final int			EFFECT_AQUA 		= 1;
	public static final int			EFFECT_BLACKBOARD 	= 2;
	public static final int			EFFECT_MONO			= 3;
	public static final int			EFFECT_NEGATIVE 	= 4;
	public static final int			EFFECT_POSTERIZE 	= 5;
	public static final int			EFFECT_SEPIA 		= 6;
	public static final int			EFFECT_SOLARIZE 	= 7;
	public static final int			EFFECT_WHITEBOARD 	= 8;
	
	// flash mode //
	public static final int			FLASH_MODE_OFF 		= 0;
	public static final int			FLASH_MODE_AUTO 	= 1;
	public static final int			FLASH_MODE_ON 		= 2;
	public static final int			FLASH_MODE_RED_EYE	= 3;
	public static final int			FLASH_MODE_TORCH 	= 4;
	
	// focus mode //
	public static final int			FOCUS_MODE_AUTO 				= 0;
	public static final int			FOCUS_MODE_CONTINUOUS_PICTURE  	= 1;
	public static final int			FOCUS_MODE_CONTINUOUS_VIDEO 	= 2;
	public static final int			FOCUS_MODE_EDOF 				= 3;
	public static final int			FOCUS_MODE_FIXED 				= 4;
	public static final int			FOCUS_MODE_INFINITY 			= 5;
	public static final int			FOCUS_MODE_MACRO 				= 6;
	
	// scene mode //
	public static final int			SCENE_MODE_AUTO				= 0;
	public static final int			SCENE_MODE_ACTION 			= 1;
	public static final int			SCENE_MODE_BARCODE 			= 2;
	public static final int			SCENE_MODE_BEACH			= 3;
	public static final int			SCENE_MODE_CANDLELIGHT 		= 4;
	public static final int			SCENE_MODE_FIREWORKS 		= 5;
	public static final int			SCENE_MODE_HDR				= 6;
	public static final int			SCENE_MODE_LANDSCAPE 		= 7;
	public static final int			SCENE_MODE_NIGHT			= 8;
	public static final int			SCENE_MODE_NIGHT_PORTRAIT	= 9;
	public static final int			SCENE_MODE_PARTY 			= 10;
	public static final int			SCENE_MODE_PORTRAIT 		= 11;
	public static final int			SCENE_MODE_SNOW 			= 12;
	public static final int			SCENE_MODE_SPORTS			= 13;
	public static final int			SCENE_MODE_STEADYPHOTO 		= 14;
	public static final int			SCENE_MODE_SUNSET 			= 15;
	public static final int			SCENE_MODE_THEATRE 			= 16;
	
	// white balance //
	public static final int			WHITE_BALANCE_AUTO 				= 0;
	public static final int			WHITE_BALANCE_CLOUDY_DAYLIGHT	= 1;
	public static final int			WHITE_BALANCE_DAYLIGHT 			= 2;
	public static final int			WHITE_BALANCE_FLUORESCENT		= 3;
	public static final int			WHITE_BALANCE_INCANDESCENT 		= 4;
	public static final int			WHITE_BALANCE_SHADE 			= 5;
	public static final int			WHITE_BALANCE_TWILIGHT			= 6;
	public static final int			WHITE_BALANCE_WARM_FLUORESCENT 	= 7;

	
// variables //
	private ICameraSurface			_surface;
	private final EngineContext		_engine;
	private Camera					_camera					= null;
    private boolean					_createdByUser			= false;
    private boolean					_previewStarted			= false;
    private boolean					_requestStartPreview	= false;
    private int						_cameraIndex			= 0;
    private String					_params					= null;
    
   // private int					_reservedBuffers = DEF_RESERVED_BUFFERS;
    //private int					_freeBuffers	= 0;
    //private int					_bufferSize		= 0;
	
	
// methods //
	
	// constructor
	public UXCamera (EngineContext eng, int cameraPreviewId)
	{
		this._engine   = eng;
		this._surface  = (ICameraSurface) _engine.GetView( cameraPreviewId );
	}
	
	
	// OnAdded
	public final void OnAdded (uxgenes.core.EngineContext eng)
	{
		if ( _surface != null ) {
			_surface.SetCamera( this );
		}
	}

	
	// OnRemoved
	public final void OnRemoved ()
	{
		Com_Close( false, false );
		
		if ( _surface != null ) {
			_surface.SetCamera( null );
		}
	}
	
	// CameraCommand
	public final void CameraCommand (int cmd, float arg0, float arg1, float arg2)
	{
		if ( _surface == null || (_camera == null && cmd != COM_OPEN) )
			return;
		
		switch ( cmd )
		{
			case COM_OPEN 					: Com_Open( (int)arg0, true );						return;
			case COM_CLOSE 					: Com_Close( (int)arg0 != 0, true );				return;
			case COM_START_FACE_DETECTION 	: Com_StartFaceDetection();							return;
			case COM_STOP_FACE_DETECTION	: Com_StopfaceDetection();							return;
			case COM_AUTO_FOCUS				: Com_AutoFocus();									return;
			case COM_UPDATE_ZOOM_INFO		: Com_UpdateZoomInfo();								return;
			// shared
			case COM_SET_ZOOM 				: Com_SetZoom( (int)arg0 );							return;
			case COM_SET_ZOOM_NORM			: Com_SetZoomNorm( arg0 );							return;
			case COM_SET_SMOOTH_ZOOM		: Com_SetSmoothZoom( (int)arg0 ); 					return;
			case COM_SET_SMOOTH_ZOOM_NORM	: Com_SetSmoothZoomNorm( arg0 );					return;
			case COM_SET_EXPOSURE 			: Com_SetExposure( (int)arg0 );						return;
			case COM_SET_EFFECT 			: Com_SetEffect( (int)arg0 );						return;
			case COM_SET_FLASH_MODE 		: Com_SetFlashMode( (int)arg0 );					return;
			case COM_SET_FOCUS_MODE 		: Com_SetFocusMode( (int)arg0 );					return;
			case COM_SET_SCENE_MODE 		: Com_SetSceneMode( (int)arg0 );					return;
			case COM_SET_WHITE_BALANCE 		: Com_SetWhiteBalance( (int)arg0 );					return;
			case COM_SET_ANTIBANDING		: Com_SetAntibanding( (int)arg0 );					return;
			case COM_SET_EXPOSURE_NORM		: Com_SetExposureNorm( arg0 );						return;
			// preview
			case COM_SET_PREVIEW_SIZE 		: Com_SetPreviewSize( (int)arg0, (int)arg1 );		return;
			case COM_SET_PREVIEW_FORMAT		: Com_SetPreviewFormat( (int)arg0 );				return;
			case COM_SET_PREVIEW_FPS 		: Com_SetPreviewFPS( (int)arg0, (int)arg0 );		return;
			case COM_SET_PREVIEW_NEAR_SIZE	: Com_SetPreviewNearSize( (int)arg0, (int)arg1 ); 	return;
			case COM_SET_PREVIEW_NEAR_FPS	: Com_SetPreviewNearFPS( (int)arg0 );				return;
			//case COM_SET_PREVIEW_BUFFERS	: Com_SetPreviewBuffers( (int)arg0 );				return;
			case COM_SET_PREVIEW_TEXTURE	: Com_SetPreviewTexture( (int)arg0 );				return;
			//case COM_START_PREVIEW			: Com_StartPreview();								return;
			//case COM_STOP_PREVIEW			: Com_StopPreview();								return;
			// picture
			case COM_TAKE_PICTURE 			: Com_TakePicture( (int)arg0 != 0 ); 				return;
			case COM_SET_PICTURE_SIZE 		: Com_SetPictureSize( (int)arg0, (int)arg1 ); 		return;
			case COM_SET_PICTURE_FORMAT		: Com_SetPictureFormat( (int)arg0 ); 				return;
			case COM_SET_PICTURE_NEAR_SIZE	: Com_SetPictureNearSize( (int)arg0, (int)arg1 ); 	return;
			case COM_SET_JPEG_QUALITY		: Com_SetJpegQuality( (int)arg0 );					return;
		}
	}
	
	
	// OnResume
	public final void OnResume ()
	{
		if ( _createdByUser ) {
			Com_Open( _cameraIndex, false );
		}
	}
	
	
	// OnPause
	public final void OnPause ()
	{
		Com_Close( true, false );
	}

	public final void OnStart () 	{}
	public final void OnStop () 	{}
	public final void OnInit () 	{}
	public final void OnDestroy () 	{}
	
	
	// GetHwCamera
	public final Camera GetHwCamera ()
	{
		return _camera;
	}

	
	// OnPreviewFrame
	public final void OnPreviewFrame (byte[] data, Camera camera)
	{
		Logger.I( TAG, "onPreviewFrame" );
		
		// if buffer size is too small
		if ( data == null || _engine == null )
			return;
		
		Camera.Parameters 	p 	 = camera.getParameters();
		Camera.Size			size = p.getPreviewSize();
		_engine.nativeLib.CameraPreview( data, size.width, size.height, p.getPreviewFormat() );
	}
	
	
	// OnFrameAvailable
	public final void OnFrameAvailable (SurfaceTexture tex)
	{
		Logger.I( TAG, "OnFrameAvailable" );
		
		if ( _engine == null )
			return;
		
		_engine.nativeLib.CameraPreviewAvailable( tex );
	}
	
	
// Camera.AutoFocusCallback //
	
	// onAutoFocus
	public final void onAutoFocus (boolean success, Camera camera)
	{
		if ( success ) {
			Com_UpdateZoomInfo();
		}
	}
	
	
// Camera.PictureCallback //
	
	// onPictureTaken
	public final void onPictureTaken (byte[] data, Camera camera)
	{
		if ( data == null || _engine == null )
			return;
		
		Camera.Parameters 	p 	 = camera.getParameters();
		Camera.Size			size = p.getPictureSize();
		_engine.nativeLib.CameraPicture( data, size.width, size.height, p.getPictureFormat() );
		
		// restart camera
		(new Handler()).postDelayed( new Runnable()
		{
			public void run ()
			{
				try
				{
					String paramStr = _camera.getParameters().flatten();
					_camera.release();
					
					_previewStarted	= false;
					_requestStartPreview = true;
					
					_camera = Camera.open();
					Camera.Parameters p = _camera.getParameters();
					p.unflatten( paramStr );
					
					try {
						_camera.setParameters( p );
					}
					catch (Exception e) {
						Logger.OnCatchException( TAG, e );
					}

					Com_StartPreview();
				}
				catch (Exception e) {
					Logger.OnCatchException( TAG, e );
					return;
				}
			}
		}, 10 );
	}

	
	
// SurfaceHolder.Callback //
	
	// surfaceChanged
	public final void surfaceChanged (SurfaceHolder holder, int format, int width, int height)
	{
		Logger.I( TAG, "surfaceChanged" );

		if ( _requestStartPreview ) {
			Com_StartPreview();
		}
	}

	
	// surfaceCreated
	public final void surfaceCreated (SurfaceHolder holder)
	{}

	
	// surfaceDestroyed
	public final void surfaceDestroyed (SurfaceHolder holder)
	{
		Logger.I( TAG, "surfaceDestroyed" );

		Com_StopPreview();
	}
	

// Commands //

	// Com_Open
	private final void Com_Open (int index, boolean fromUser)
	{
		if ( _engine == null || _engine.nativeLib == null )
		{
			Logger.E( TAG, "NativeLib must be initialized" );
			return;
		}
		
    	if ( _camera == null )
    	{
    		if ( index < 0 || index >= Camera.getNumberOfCameras() ) {
    			Logger.E( TAG, "Camera with index " + index + " not supported!" );
    			index = 0;
    		}
    		
    		try {
    			_camera = Camera.open( index );
    			_cameraIndex = index;
    		}
    		catch (Exception e) {
    			Logger.OnCatchException( TAG, e );
    			return;
    		}
    		
    		_UpdateCameraParams();
    		
    		_DisableShooterSound();
    		
    		if ( _params != null )
    		{
    			try {
    				Camera.Parameters p =_camera.getParameters();
    				p.unflatten( _params );
    				_camera.setParameters( p );
    			}
    			catch (Exception e) {
    				Logger.OnCatchException( TAG, e );
    			}
    		}

    		if ( fromUser ) {
    			_createdByUser = true;
    		}
    		
    		Logger.I( TAG, "Camera opened" );
    		
    		if ( fromUser || _requestStartPreview ) {
    			Com_StartPreview();
    		}
    	}
	}
	
	
	// Com_Close
	private final void Com_Close (boolean saveState, boolean fromUser)
	{
		if ( _camera != null )
    	{
			_requestStartPreview = _previewStarted;
			
			Com_StopPreview();
			
			if ( saveState ) {
				_params = _camera.getParameters().flatten();
			}
			
    		_camera.setPreviewCallback( null );
    		_camera.stopPreview();
    		_camera.release();
    		_camera = null;
    		
    		_previewStarted = false;
    		
    		if ( fromUser ) {
    			_createdByUser = false;
    		}
    		
    		Logger.I( TAG, "Camera closed" );
    	}
	}
	
	
	// Com_StartFaceDetection
	private final void Com_StartFaceDetection ()
	{
		if ( UXUtils.CheckAPIVersion( 14 ) )
		{
			try {
				_camera.startFaceDetection();
				//_camera.setFaceDetectionListener( this );
			}
			catch (Exception e) {
				Logger.OnCatchException( TAG, e );
			}
		}
	}
	
	
	// Com_StopfaceDetection
	private final void Com_StopfaceDetection ()
	{
		if ( UXUtils.CheckAPIVersion( 14 ) )
		{
			try {
				_camera.stopFaceDetection();
			}
			catch (Exception e) {
				Logger.OnCatchException( TAG, e );
			}
		}
	}
	
	
	// Com_AutoFocus
	private final void Com_AutoFocus ()
	{
		_camera.autoFocus( this );
	}
	
	
	// Com_SetPreviewSize
	private final void Com_SetPreviewSize (int width, int height)
	{
		try {
			Camera.Parameters	p = _camera.getParameters();
			p.setPreviewSize( width, height );
			_camera.setParameters( p );

			Com_UpdateZoomInfo();

			//_UpdateCallbackBuffers();
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPreviewFormat
	private final void Com_SetPreviewFormat (int format)
	{
		try {
			Camera.Parameters	p = _camera.getParameters();
			p.setPreviewFormat( format );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPreviewFPS
	private final void Com_SetPreviewFPS (int minFps, int maxFps)
	{
		try {
			Camera.Parameters	p = _camera.getParameters();
			p.setPreviewFpsRange( minFps, maxFps );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPreviewNearSize
	private final void Com_SetPreviewNearSize (int width, int height)
	{
		try {
			Camera.Parameters	p 	 = _camera.getParameters();
	    	List<Camera.Size> 	list = p.getSupportedPreviewSizes();

	    	int	w = Math.max( width, height );
	    	int h = Math.min( width, height );
	    	
	    	if ( !list.isEmpty() )
	    	{
		    	Camera.Size	nearest 	= list.get(0);
		    	int			difference 	= Math.abs( nearest.width - w ) + Math.abs( nearest.height - h );
		    	
		    	for (Camera.Size s : list)
		    	{
		        	int	diff = Math.abs( s.width - w ) + Math.abs( s.height - h );
		    		
		        	if ( diff < difference ) {
		        		difference = diff;
		        		nearest    = s;
		        	}
		    	}
		    	
		    	p.setPreviewSize( nearest.width, nearest.height );
		    	_camera.setParameters( p );
	    	}
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPreviewNearFPS
	private final void Com_SetPreviewNearFPS (int fps)
	{
		try {
			Camera.Parameters	p 	 = _camera.getParameters();
	    	List<int[]> 		list = p.getSupportedPreviewFpsRange();
	    	
	    	if ( !list.isEmpty() )
	    	{
		    	int[] nearest    = list.get(0);
		    	int   difference = Math.abs( nearest[0] - fps ) + Math.abs( nearest[1] - fps );
		    	
		    	for (int[] v : list)
		    	{
		    		int diff = Math.abs( v[0] - fps ) + Math.abs( v[1] - fps );
		    		
		    		if ( diff < difference ) {
		    			difference = diff;
		    			nearest    = v;
		    		}
		    	}
		    	p.setPreviewFpsRange( nearest[0], nearest[1] );
		    	_camera.setParameters( p );
	    	}
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	/*// Com_SetPreviewBuffers
	private void Com_SetPreviewBuffers (final int count)
	{
		final int newCount = UXUtils.Clamp( count, DEF_RESERVED_BUFFERS, MAX_RESERVED_BUFFERS );
		
		_AddCallbackBuffers( newCount );
		_reservedBuffers = count;	// TODO
	}*/
	
	
	// Com_SetPreviewTexture
	private final void Com_SetPreviewTexture (int id)
	{
		if ( _surface != null ) {
			Com_StopPreview();
			_requestStartPreview = true;
			_surface.SetCamera( null );
		}
		
		_surface = new CameraTexturePreview( id, _engine.GetOpenGLSurfaceView() );
		_surface.SetCamera( this );
		
		if ( _requestStartPreview ) {
			Com_StartPreview();
		}
	}
	
	
	// Com_StartPreview
	private final void Com_StartPreview ()
	{
		if ( _camera == null || _previewStarted ||
			 _surface == null || !_surface.IsCreated() )
		{
			_requestStartPreview = !_previewStarted;
			return;
		}
		
		try {
			_surface.OnStartPreview();
			
			_camera.startPreview();
			_previewStarted = true;
			_requestStartPreview = false;
			
			Logger.I( TAG, "preview started" );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_StopPreview
	private final void Com_StopPreview ()
	{
		if ( _camera == null || !_previewStarted || _surface == null || !_surface.IsCreated() )
			return;
		
		try {
			_camera.stopPreview();
			_previewStarted = false;

			_surface.OnStopPreview();
			
			Logger.I( TAG, "preview stopped" );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_TakePicture
	private final void Com_TakePicture (boolean autoFocus)
	{
		try {
			if ( autoFocus )
			{
				_camera.autoFocus( new Camera.AutoFocusCallback()
				{
					public void onAutoFocus (boolean success, Camera camera) {
						camera.takePicture( null, null, null, UXCamera.this );
					}
				});
			}
			else {
				_camera.takePicture( null, null, null, this );
			}
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetZoom
	private final void Com_SetZoom (int zoom)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			p.setZoom( zoom );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetZoomNorm
	private final void Com_SetZoomNorm (float zoom)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			int	max 		= p.getMaxZoom();
			int newZoom		= Math.round( max * zoom );
			
			if ( newZoom == p.getZoom() )
				return;
			
			p.setZoom( newZoom );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetSmoothZoomNorm
	private final void Com_SetSmoothZoomNorm (float zoom)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			
			if ( !p.isSmoothZoomSupported() ) {
				Logger.E( TAG, "smooth zoom not supported" );
				return;
			}

			int	max 		= p.getMaxZoom();
			int newZoom		= Math.round( max * zoom );
			
			_camera.startSmoothZoom( newZoom );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetSmoothZoom
	private final void Com_SetSmoothZoom (int zoom)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			
			if ( !p.isSmoothZoomSupported() ) {
				Logger.E( TAG, "smooth zoom not supported" );
				return;
			}
			
			_camera.startSmoothZoom( zoom );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetExposure
	private final void Com_SetExposure (int value)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			p.setExposureCompensation( value );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetExposureNorm
	private final void Com_SetExposureNorm (float value)
	{
		try {
			Camera.Parameters	p = _camera.getParameters();
	    	
	    	int 	min  = p.getMinExposureCompensation();
	    	int 	max  = p.getMaxExposureCompensation();
	    	
	    	int		newValue = (int)( value * (max - min) + 0.5f ) + min;
	    	
	    	if ( newValue == p.getExposureCompensation() )
	    		return;
	    	
	    	p.setExposureCompensation( newValue );

    		_camera.setParameters( p );
    	}
    	catch (Exception e) {
    		Logger.OnCatchException( TAG, e );
    	}
	}
	
	
	// Com_SetEffect
	private final void Com_SetEffect (int value)
	{
		try {
			Camera.Parameters 	p 		= _camera.getParameters();
			String				effect 	= null;
			
			switch ( value )
			{
				case EFFECT_AQUA 		:	effect = Camera.Parameters.EFFECT_AQUA;
				case EFFECT_BLACKBOARD 	:	effect = Camera.Parameters.EFFECT_BLACKBOARD;
				case EFFECT_MONO		:	effect = Camera.Parameters.EFFECT_MONO;
				case EFFECT_NEGATIVE 	:	effect = Camera.Parameters.EFFECT_NEGATIVE;
				case EFFECT_POSTERIZE 	:	effect = Camera.Parameters.EFFECT_POSTERIZE;
				case EFFECT_SEPIA 		:	effect = Camera.Parameters.EFFECT_SEPIA;
				case EFFECT_SOLARIZE 	:	effect = Camera.Parameters.EFFECT_SOLARIZE;
				case EFFECT_WHITEBOARD 	:	effect = Camera.Parameters.EFFECT_WHITEBOARD;
				case EFFECT_NONE 		:
				default					:	effect = Camera.Parameters.EFFECT_NONE;
			}
			p.setColorEffect( effect );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetFlashMode
	private final void Com_SetFlashMode (int value)
	{
		try {
			Camera.Parameters 	p 	 = _camera.getParameters();
			String				mode = null;
			
			switch ( value )
			{
				case FLASH_MODE_AUTO 	:	mode = Camera.Parameters.FLASH_MODE_AUTO;
				case FLASH_MODE_ON 		:	mode = Camera.Parameters.FLASH_MODE_ON;
				case FLASH_MODE_RED_EYE	:	mode = Camera.Parameters.FLASH_MODE_RED_EYE;
				case FLASH_MODE_TORCH 	:	mode = Camera.Parameters.FLASH_MODE_TORCH;
				case FLASH_MODE_OFF 	:
				default					:	mode = Camera.Parameters.FLASH_MODE_OFF;
			}
			p.setFlashMode( mode );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetFocusMode
	private final void Com_SetFocusMode (int value)
	{
		try {
			Camera.Parameters	p 	 = _camera.getParameters();
			String				mode = null;
			
			switch ( value )
			{
				//case FOCUS_MODE_CONTINUOUS_PICTURE  :	mode = Camera.Parameters. FOCUS_MODE_CONTINUOUS_PICTURE;
				case FOCUS_MODE_CONTINUOUS_VIDEO 	:	mode = Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO;
				case FOCUS_MODE_EDOF 				:	mode = Camera.Parameters.FOCUS_MODE_EDOF;
				case FOCUS_MODE_FIXED 				:	mode = Camera.Parameters.FOCUS_MODE_FIXED;
				case FOCUS_MODE_INFINITY 			:	mode = Camera.Parameters.FOCUS_MODE_INFINITY;
				case FOCUS_MODE_MACRO 				:	mode = Camera.Parameters.FOCUS_MODE_MACRO;
				case FOCUS_MODE_AUTO 				:
				default								: 	mode = Camera.Parameters.FOCUS_MODE_AUTO;
			}
			p.setFocusMode( mode );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetSceneMode
	private final void Com_SetSceneMode (int value)
	{
		try {
			Camera.Parameters	p 	 = _camera.getParameters();
			String				mode = null;
			
			switch ( value )
			{
				case SCENE_MODE_ACTION 			:	mode = Camera.Parameters.SCENE_MODE_ACTION;
				case SCENE_MODE_BARCODE 		:	mode = Camera.Parameters.SCENE_MODE_BARCODE;
				case SCENE_MODE_BEACH			:	mode = Camera.Parameters.SCENE_MODE_BEACH;
				case SCENE_MODE_CANDLELIGHT 	:	mode = Camera.Parameters.SCENE_MODE_CANDLELIGHT;
				case SCENE_MODE_FIREWORKS 		:	mode = Camera.Parameters.SCENE_MODE_FIREWORKS;
				//case SCENE_MODE_HDR				:	mode = Camera.Parameters.SCENE_MODE_HDR;
				case SCENE_MODE_LANDSCAPE 		:	mode = Camera.Parameters.SCENE_MODE_LANDSCAPE;
				case SCENE_MODE_NIGHT			:	mode = Camera.Parameters.SCENE_MODE_NIGHT;
				case SCENE_MODE_NIGHT_PORTRAIT	:	mode = Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT;
				case SCENE_MODE_PARTY 			:	mode = Camera.Parameters.SCENE_MODE_PARTY;
				case SCENE_MODE_PORTRAIT 		:	mode = Camera.Parameters.SCENE_MODE_PORTRAIT;
				case SCENE_MODE_SNOW 			:	mode = Camera.Parameters.SCENE_MODE_SNOW;
				case SCENE_MODE_SPORTS			:	mode = Camera.Parameters.SCENE_MODE_SPORTS;
				case SCENE_MODE_STEADYPHOTO 	:	mode = Camera.Parameters.SCENE_MODE_STEADYPHOTO;
				case SCENE_MODE_SUNSET 			:	mode = Camera.Parameters.SCENE_MODE_SUNSET;
				case SCENE_MODE_THEATRE 		:	mode = Camera.Parameters.SCENE_MODE_THEATRE;
				case SCENE_MODE_AUTO			:
				default							: 	mode = Camera.Parameters.SCENE_MODE_AUTO;
			}
			p.setSceneMode( mode );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetWhiteBalance
	private final void Com_SetWhiteBalance (int value)
	{
		try {
			Camera.Parameters	p	 = _camera.getParameters();
			String				mode = null;
			
			switch ( value )
			{
				case WHITE_BALANCE_CLOUDY_DAYLIGHT	:	mode = Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT;
				case WHITE_BALANCE_DAYLIGHT 		:	mode = Camera.Parameters.WHITE_BALANCE_DAYLIGHT;
				case WHITE_BALANCE_FLUORESCENT		:	mode = Camera.Parameters.WHITE_BALANCE_FLUORESCENT;
				case WHITE_BALANCE_INCANDESCENT 	:	mode = Camera.Parameters.WHITE_BALANCE_INCANDESCENT;
				case WHITE_BALANCE_SHADE 			:	mode = Camera.Parameters.WHITE_BALANCE_SHADE;
				case WHITE_BALANCE_TWILIGHT			:	mode = Camera.Parameters.WHITE_BALANCE_TWILIGHT;
				case WHITE_BALANCE_WARM_FLUORESCENT :	mode = Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT;
				case WHITE_BALANCE_AUTO 			:
				default								: 	mode = Camera.Parameters.WHITE_BALANCE_AUTO;
			}
			p.setWhiteBalance( mode );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetAntibanding
	private final void Com_SetAntibanding (int value)
	{
		try {
			Camera.Parameters	p 	 = _camera.getParameters();
			String				mode = null;
			
			switch ( value )
			{
				case ANTIBANDING_50HZ  	:	mode = Camera.Parameters.ANTIBANDING_50HZ;
				case ANTIBANDING_60HZ 	:	mode = Camera.Parameters.ANTIBANDING_60HZ;
				case ANTIBANDING_AUTO 	:	mode = Camera.Parameters.ANTIBANDING_AUTO;
				case ANTIBANDING_OFF  	:
				default					:	mode = Camera.Parameters.ANTIBANDING_OFF;
			}
			p.setAntibanding( mode );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPictureSize
	private final void Com_SetPictureSize (int width, int height)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			p.setPictureSize( width, height );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPictureFormat
	private final void Com_SetPictureFormat (int format)
	{
		try {
			Camera.Parameters p = _camera.getParameters();
			p.setPictureFormat( format );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetPictureNearSize
	private final void Com_SetPictureNearSize (int width, int height)
	{
		try {
			Camera.Parameters	p 	 = _camera.getParameters();
	    	List<Camera.Size> 	list = p.getSupportedPictureSizes();

	    	int	w = Math.max( width, height );
	    	int h = Math.min( width, height );
	    	
	    	if ( !list.isEmpty() )
	    	{
		    	Camera.Size	nearest 	= list.get(0);
		    	int			difference 	= Math.abs( nearest.width - w ) + Math.abs( nearest.height - h );
		    	
		    	for (Camera.Size s : list)
		    	{
		        	int	diff = Math.abs( s.width - w ) + Math.abs( s.height - h );
		    		
		        	if ( diff < difference ) {
		        		difference = diff;
		        		nearest    = s;
		        	}
		    	}
		    	
		    	p.setPictureSize( nearest.width, nearest.height );
		    	_camera.setParameters( p );
	    	}
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	// Com_SetJpegQuality
	private final void Com_SetJpegQuality (int quality)
	{
		try {
			Camera.Parameters	p = _camera.getParameters();
			
			p.setJpegQuality( UXUtils.Clamp( quality, 0, 100 ) );
			_camera.setParameters( p );
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}
	
	
	
// Utils //
	
	/*// _AddCallbackBuffers
	private void _AddCallbackBuffers (int number)
	{
		final int dataSize = _GetPreviewSize();
		
		_bufferSize = dataSize;
		
		try {
			for (int i = 0; i < number; ++i) {
				_camera.addCallbackBuffer( new byte[ dataSize ] );
			}
		}
		catch (Exception e) {
			Logger.OnCatchException( TAG, e );
		}
	}*/
	
	
	/*// _UpdateCallbackBuffers
	private void _UpdateCallbackBuffers ()
	{
		final int	dataSize = _GetPreviewSize();
		
		if ( dataSize <= _bufferSize )
			return;
		
		_AddCallbackBuffers( _reservedBuffers );
	}*/
	
	
	/*// _GetPreviewSize
	private final int _GetPreviewSize ()
	{
		Camera.Parameters	p 	 = _camera.getParameters();
		Camera.Size			size = p.getPreviewSize();
		int					fmt	 = p.getPreviewFormat();
		int					bpp  = ImageFormat.getBitsPerPixel( fmt );
		int					dataSize = 0;
		
		if ( bpp > 0 )
		{
			dataSize = size.width * size.height * bpp / 8;
		}
		else
		{
			switch ( fmt )
			{
				case ImageFormat.NV21 :		dataSize = size.width * size.height * 3 / 2;	break;
				case ImageFormat.RGB_565 :	dataSize = size.width * size.height * 2;		break;
				default :
					Logger.E( TAG, "unknown image format: " + fmt );
					dataSize *= 4;
					break;
			}
		}
		return dataSize;
	}*/
	
	
	// _UpdateCameraParams
	private final void _UpdateCameraParams ()
	{
		if ( _engine == null )
			return;
		
		Camera.Parameters	p = _camera.getParameters();
		
		_engine.nativeLib.CameraSetStaticParams(
			p.getMinExposureCompensation(), p.getMaxExposureCompensation(), p.getExposureCompensationStep(),	// exposure
			_IntListToIntArray( p.getSupportedPictureFormats() ),
			_SizeListToIntArray( p.getSupportedPictureSizes() ),
			_IntListToIntArray( p.getSupportedPreviewFormats() ),
			_SizeListToIntArray( p.getSupportedPreviewSizes() ),
			_Int2ListToIntArray( p.getSupportedPreviewFpsRange() ),
			_AntibandingListToIntArray( p.getSupportedAntibanding() ),
			_EffectListToIntArray( p.getSupportedColorEffects() ),
			_FlashModeListToIntArray( p.getSupportedFlashModes() ),
			_FocusModeListToIntArray( p.getSupportedFocusModes() ),
			_SceneModeListToIntArray( p.getSupportedSceneModes() ),
			_WhiteBalanceToIntArray( p.getSupportedWhiteBalance() )
		);
		
		Com_UpdateZoomInfo();
	}
	
	
	// Com_UpdateZoomInfo
	private final void Com_UpdateZoomInfo ()
	{
		if ( _engine == null )
			return;
		
		Camera.Parameters	p = _camera.getParameters();
		float[]				f = new float[3];
		
		p.getFocusDistances( f );
		
		_engine.nativeLib.CameraZoomChanged(
				p.getZoom(), p.getMaxZoom(),
				f[ Camera.Parameters.FOCUS_DISTANCE_NEAR_INDEX ],
				f[ Camera.Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX ],
				f[ Camera.Parameters.FOCUS_DISTANCE_FAR_INDEX ],
				p.getFocalLength(),
				p.getVerticalViewAngle(), p.getHorizontalViewAngle() );
	}
	
	
	// _DisableShooterSound
	private final void _DisableShooterSound ()
	{
		if ( UXUtils.CheckAPIVersion( 17 ) )
		{
			try {
				Camera.CameraInfo	info = new Camera.CameraInfo();
				Camera.getCameraInfo( _cameraIndex, info );
				
				if ( info.canDisableShutterSound ) {
					_camera.enableShutterSound( false );
				}
			}
			catch (Exception e) {
				Logger.OnCatchException( TAG, e );
			}
		}
	}
	
	
	// _ListToIntArray
	private static final int[] _IntListToIntArray (List<Integer> list)
	{
		int[]	res = new int[ list.size() ];
		int		i   = 0;
		
		for (Integer v : list) {
			res[i] = v;
			++i;
		}
		return res;
	}
	
	
	// _ListToIntArray
	private static final int[] _Int2ListToIntArray (List<int[]> list)
	{
		int[]	res = new int[ list.size()*2 ];
		int		i   = 0;
		
		for (int[] v : list) {
			res[i*2+0] = v[0];
			res[i*2+1] = v[1];
			++i;
		}
		return res;
	}
	
	
	// _ListToIntArray
	private static final int[] _SizeListToIntArray (List<Camera.Size> list)
	{
		int[]	res = new int[ list.size()*2 ];
		int		i   = 0;
		
		for (Camera.Size v : list) {
			res[i*2+0] = v.width;
			res[i*2+1] = v.height;
			++i;
		}
		return res;
	}
	
	
	// _AntibandingListToIntArray
	private static final int[] _AntibandingListToIntArray (List<String> list)
	{
		int[]	res = new int[ list.size() ];
		int		i	= 0;
		
		for (String s : list)
		{
			int	value = -1;
			if ( s.equals( Camera.Parameters.ANTIBANDING_OFF ) )	value = ANTIBANDING_OFF;	else
			if ( s.equals( Camera.Parameters.ANTIBANDING_AUTO ) )	value = ANTIBANDING_AUTO;	else
			if ( s.equals( Camera.Parameters.ANTIBANDING_50HZ ) )	value = ANTIBANDING_50HZ;	else
			if ( s.equals( Camera.Parameters.ANTIBANDING_60HZ ) )	value = ANTIBANDING_60HZ;
			res[i] = value;
			++i;
		}
		return res;
	}
	
	
	// _EffectListToIntArray
	private static final int[] _EffectListToIntArray (List<String> list)
	{
		int[]	res = new int[ list.size() ];
		int		i	= 0;
		
		for (String s : list)
		{
			int	value = -1;
			if ( s.equals( Camera.Parameters.EFFECT_AQUA ) )		value = EFFECT_AQUA;		else
			if ( s.equals( Camera.Parameters.EFFECT_BLACKBOARD ) )	value = EFFECT_BLACKBOARD;	else
			if ( s.equals( Camera.Parameters.EFFECT_MONO ) )		value = EFFECT_MONO;		else
			if ( s.equals( Camera.Parameters.EFFECT_NEGATIVE ) )	value = EFFECT_NEGATIVE;	else
			if ( s.equals( Camera.Parameters.EFFECT_NONE ) )		value = EFFECT_NONE;		else
			if ( s.equals( Camera.Parameters.EFFECT_POSTERIZE ) )	value = EFFECT_POSTERIZE;	else
			if ( s.equals( Camera.Parameters.EFFECT_SEPIA ) )		value = EFFECT_SEPIA;		else
			if ( s.equals( Camera.Parameters.EFFECT_SOLARIZE ) )	value = EFFECT_SOLARIZE;	else
			if ( s.equals( Camera.Parameters.EFFECT_WHITEBOARD ) )	value = EFFECT_WHITEBOARD;
			res[i] = value;
			++i;
		}
		return res;
	}
	
	
	// _FlashModeListToIntArray
	private static final int[] _FlashModeListToIntArray (List<String> list)
	{
		int[]	res = new int[ list.size() ];
		int		i	= 0;
		
		for (String s : list)
		{
			int value = -1;
			if ( s.equals( Camera.Parameters.FLASH_MODE_AUTO ) )	value = FLASH_MODE_AUTO;	else
			if ( s.equals( Camera.Parameters.FLASH_MODE_OFF ) )		value = FLASH_MODE_OFF;		else
			if ( s.equals( Camera.Parameters.FLASH_MODE_ON ) )		value = FLASH_MODE_ON;		else
			if ( s.equals( Camera.Parameters.FLASH_MODE_RED_EYE ) )	value = FLASH_MODE_RED_EYE;	else
			if ( s.equals( Camera.Parameters.FLASH_MODE_TORCH ) )	value = FLASH_MODE_TORCH;
			res[i] = value;
			++i;
		}
		return res;
	}
	
	
	// _FocusModeListToIntArray
	private static final int[] _FocusModeListToIntArray (List<String> list)
	{
		int[]	res = new int[ list.size() ];
		int		i	= 0;
		
		for (String s : list)
		{
			int	value = -1;
			if ( s.equals( Camera.Parameters.FOCUS_MODE_AUTO ) )				value = FOCUS_MODE_AUTO;				else
			if ( s.equals( Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE ) )	value = FOCUS_MODE_CONTINUOUS_PICTURE;	else
			if ( s.equals( Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO ) )	value = FOCUS_MODE_CONTINUOUS_VIDEO;	else
			if ( s.equals( Camera.Parameters.FOCUS_MODE_EDOF ) )				value = FOCUS_MODE_EDOF;				else
			if ( s.equals( Camera.Parameters.FOCUS_MODE_FIXED ) )				value = FOCUS_MODE_FIXED;				else
			if ( s.equals( Camera.Parameters.FOCUS_MODE_INFINITY ) )			value = FOCUS_MODE_INFINITY;			else
			if ( s.equals( Camera.Parameters.FOCUS_MODE_MACRO ) )				value = FOCUS_MODE_MACRO;
			res[i] = value;
			++i;
		}
		return res;
	}
	
	
	// _SceneModeListToIntArray
	private static final int[] _SceneModeListToIntArray (List<String> list)
	{
		int[]	res = new int[ list.size() ];
		int		i	= 0;
		
		for (String s : list)
		{
			int	value = -1;
			if ( s.equals( Camera.Parameters.SCENE_MODE_ACTION ) )			value = SCENE_MODE_ACTION;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_AUTO ) )			value = SCENE_MODE_AUTO;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_BARCODE ) )			value = SCENE_MODE_BARCODE;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_BEACH ) )			value = SCENE_MODE_BEACH;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_CANDLELIGHT ) )		value = SCENE_MODE_CANDLELIGHT;		else
			if ( s.equals( Camera.Parameters.SCENE_MODE_FIREWORKS ) )		value = SCENE_MODE_FIREWORKS;		else
			if ( s.equals( Camera.Parameters.SCENE_MODE_HDR ) )				value = SCENE_MODE_HDR;				else
			if ( s.equals( Camera.Parameters.SCENE_MODE_LANDSCAPE ) )		value = SCENE_MODE_LANDSCAPE;		else
			if ( s.equals( Camera.Parameters.SCENE_MODE_NIGHT ) )			value = SCENE_MODE_NIGHT;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_NIGHT_PORTRAIT ) )	value = SCENE_MODE_NIGHT_PORTRAIT;	else
			if ( s.equals( Camera.Parameters.SCENE_MODE_PARTY ) ) 			value = SCENE_MODE_PARTY;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_PORTRAIT ) )		value = SCENE_MODE_PORTRAIT;		else
			if ( s.equals( Camera.Parameters.SCENE_MODE_SNOW ) )			value = SCENE_MODE_SNOW;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_SPORTS ) )			value = SCENE_MODE_SPORTS;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_STEADYPHOTO ) )		value = SCENE_MODE_STEADYPHOTO;		else
			if ( s.equals( Camera.Parameters.SCENE_MODE_SUNSET ) )			value = SCENE_MODE_SUNSET;			else
			if ( s.equals( Camera.Parameters.SCENE_MODE_THEATRE ) )			value = SCENE_MODE_THEATRE;
			res[i] = value;
			++i;
		}
		return res;
	}
	
	
	// _WhiteBalanceToIntArray
	private static final int[] _WhiteBalanceToIntArray (List<String> list)
	{
		int[]	res = new int[ list.size() ];
		int		i	= 0;
		
		for (String s : list)
		{
			int	value = -1;
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_AUTO ) )				value = WHITE_BALANCE_AUTO;				else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_CLOUDY_DAYLIGHT ) )	value = WHITE_BALANCE_CLOUDY_DAYLIGHT;	else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_DAYLIGHT ) )			value = WHITE_BALANCE_DAYLIGHT;			else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_FLUORESCENT ) )		value = WHITE_BALANCE_FLUORESCENT;		else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_INCANDESCENT ) )		value = WHITE_BALANCE_INCANDESCENT;		else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_SHADE ) )			value = WHITE_BALANCE_SHADE;			else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_TWILIGHT ) )			value = WHITE_BALANCE_TWILIGHT;			else
			if ( s.equals( Camera.Parameters.WHITE_BALANCE_WARM_FLUORESCENT ) )	value = WHITE_BALANCE_WARM_FLUORESCENT;
			res[i] = value;
			++i;
		}
		return res;
	}

	// #endif CAMERA
}
